package com.lantosec.hmrp.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lantosec.hmrp.core.kit.PageVO;
import com.lantosec.hmrp.core.kit.Result;
import com.lantosec.hmrp.core.kit.tree.TreeNodeVo;
import com.lantosec.hmrp.core.util.UUIDUtils;
import com.lantosec.hmrp.modules.system.entity.SysDept;
import com.lantosec.hmrp.modules.system.entity.SysDeptPosition;
import com.lantosec.hmrp.modules.system.entity.SysDeptUser;
import com.lantosec.hmrp.modules.system.mapper.SysDeptMapper;
import com.lantosec.hmrp.modules.system.service.ISysDeptService;
import com.lantosec.hmrp.modules.system.vo.SysDeptVO;
import com.lantosec.hmrp.modules.system.vo.SysUserVO;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 部门表 服务实现类
 * </p>
 *
 * @author AutoCode
 * @since 2020-02-12
 */
@Service
@Primary
@Log4j2
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements ISysDeptService {

    /**
     * 更新部门管理排序
     * @param id
     * @param deptOrder
     */
    @Override
    public void updateOrder(String id, Integer deptOrder) {
        SysDept sysDept = new SysDept();
        sysDept.setDeptOrder(deptOrder);
        baseMapper.update(sysDept,new QueryWrapper<SysDept>().eq(SysDept.ColName.dept_id.toString(),id));
    }

    /**
     * 获取所有部门(分页)
     * @param page
     * @return
     */
    @Override
    public List<SysDeptVO> getSysDeptPage(PageVO<SysDeptVO> page) {
        List<SysDeptVO> list = baseMapper.getSysDeptPage(page);
        page.setRecords(list);
        return list;

    }

    /**
     * 更新部门岗位
     * @param id
     * @param positions
     */
    @Override
    public void updatePosition(String id, String positions) {
        SysDept sysDept = new SysDept();
        sysDept.setPositions(positions);
        baseMapper.update(sysDept,new QueryWrapper<SysDept>().eq(SysDept.ColName.dept_id.toString(),id));
    }

    /**
     * 获得部门岗位树
     * @return
     */
    @Override
    public List<TreeNodeVo> getDeptPositionTree() {
        List<TreeNodeVo> list = deptNodes(null);
        List tree = new ArrayList<TreeNodeVo>();
        if (list != null && list.size() > 0) {
            list.forEach(node -> {
                if (!node.isLeaf()) {
                    List<TreeNodeVo> children = deptPosition(node.getKey());
                    node.setChildren(children);
                    //查询部门下的岗位
                    List<SysDeptPosition> sysDeptPositionList = baseMapper.getSysDeptPosition(node.getKey());
                    sysDeptPositionList.forEach(param->{
                        //查询部门岗位下的人员
                        List<SysDeptUser> sysDeptUsers = baseMapper.getSysDeptUserSum(param.getDeptId(),param.getPositionId());
                        children.add(new TreeNodeVo(node.getKey()+"-"+param.getPositionId(),param.getPositionName()+"-"+node.getTitle(),param.getPositionId(),sysDeptUsers.size()));
                    });
                }
                tree.add(node);
            });
        }
        return tree;
    }

    /**
     * 获得部门人员岗位树
     * @return
     */
    @Override
    public List<TreeNodeVo> getDeptUserTree() {
        List<TreeNodeVo> list = deptNodes(null);
        List tree = new ArrayList<TreeNodeVo>();
        if (list != null && list.size() > 0) {
            list.forEach(node -> {
                if (!node.isLeaf()) {
                    List<TreeNodeVo> children = deptPosition(node.getKey());
                    node.setChildren(children);
                    //查询部门下的人员岗位
                    List<SysDeptUser> sysDeptUserList = baseMapper.getSysDeptUserPosition(node.getKey());
                    sysDeptUserList.forEach(param->{
                        children.add(new TreeNodeVo(param.getUserId()+"-"+param.getPositionId(),param.getName(),param.getPositionName()));
                    });
                }
                tree.add(node);
            });
        }
        return tree;
    }

    @Override
    public List<TreeNodeVo> getDeptTreeByType(String deptId,String deptType) {
        List<SysDept> list = new ArrayList<>();
        if(StringUtils.isNotEmpty(deptId)){
            //查出所有的部门
            list = baseMapper.selectList(new QueryWrapper<SysDept>().eq(SysDept.ColName.parent_id.toString(),deptId)
                                                                    .eq(deptType != null,SysDept.ColName.dept_type.toString(),deptType));

        }else{
            list = baseMapper.selectList(new QueryWrapper<SysDept>().isNull(SysDept.ColName.parent_id.toString())
                                                                    .eq(deptType != null,SysDept.ColName.dept_type.toString(),deptType));
        }
        List<TreeNodeVo> nodes = new ArrayList<TreeNodeVo>();
        for(int i=0;i<list.size();i++){
            String parentId = list.get(i).getDeptId();
            if(null != parentId){
                //用父类节点为空的id赋值给父id去查子节点
                List<TreeNodeVo> list1 = getDeptTreeByType(parentId,deptType);
                nodes.add(new TreeNodeVo(list.get(i).getDeptId(),list.get(i).getDeptName(),list1));
            }
        }
        return nodes;
    }

    @Override
    public Result deleteDeptInfo(String ids) {
        //先查询部门下是否有人员信息
        List<SysDeptUser> sysDeptUserList = baseMapper.getUserInfo(ids);
        if(CollectionUtils.isNotEmpty(sysDeptUserList)){
            return Result.ok("操作失败,该部门下有人员信息",false);
        }
        //查询部门下是否有岗位信息
        List<SysDeptPosition> sysDeptPositions = baseMapper.getSysDeptPosition(ids);
        if(CollectionUtils.isNotEmpty(sysDeptPositions)){
            return Result.ok("操作失败,该部门下有岗位信息",false);
        }
        else {
            this.removeByIds(Arrays.asList(ids.split(",")));
            return Result.ok();
        }
    }

    @Override
    public SysDeptUser getDeptByUserId(String userId) {
        SysDeptUser sysDeptUser = baseMapper.getDeptByUserId(userId);
        return sysDeptUser;
    }

    @Override
    public void addUserFromDept(SysUserVO sysUserVO) {

    }

    public List<TreeNodeVo> deptPosition(String deptId) {
        List<TreeNodeVo> list = deptNodes(deptId);
        List tree = new ArrayList<TreeNodeVo>();
        if (list != null && list.size() > 0) {
            list.forEach(node -> {
                if (!node.isLeaf()) {
                    List<TreeNodeVo> children = deptTree(node.getKey());
                    List<SysDeptPosition> sysDeptPositionList = baseMapper.getSysDeptPosition(node.getKey());
                    sysDeptPositionList.forEach(param->{
                        children.add(new TreeNodeVo(node.getKey()+"-"+param.getPositionId(),param.getPositionName()+"-"+node.getTitle(),param.getPositionId()));
                    });
                    node.setChildren(children);
                }
                tree.add(node);
            });
        }
        return tree;
    }


    /**
     * 获得部门树
     * @return
     */
    @Override
    public List<TreeNodeVo> deptTree() {
        return deptTree(null);
    }

    /**
     * 根据指定ID查询对应的部门树
     *
     * @param deptId 部门ID
     * @return 字典树
     */
    @Override
    public List<TreeNodeVo> deptTree(String deptId) {
        List<TreeNodeVo> list = deptNodes(deptId);
        List tree = new ArrayList<TreeNodeVo>();
        if (list != null && list.size() > 0) {
            list.forEach(node -> {
                if (!node.isLeaf()) {
                    List<TreeNodeVo> children = deptTree(node.getKey());
                    node.setChildren(children);
                }
                tree.add(node);
            });
        }
        return tree;
    }

    /**
     * 获得指定Id下的部门树节点，不包含节点下的子节点
     *
     * @param deptId 部门ID
     * @return 节点列表
     */
    public List<TreeNodeVo> deptNodes(String deptId) {
        List<SysDept> list = getDeptById(deptId);
        if (list != null && list.size() > 0) {
            List<TreeNodeVo> nodes = new ArrayList<TreeNodeVo>();
            list.forEach(menu -> {
                nodes.add(new TreeNodeVo(menu.getDeptId(), menu.getDeptName(),menu.getDeptId()));
            });
            return nodes;
        }
        return new ArrayList<TreeNodeVo>();
    }

    /**
     * 查询父类部门为ID下的子部门
     * @param id
     * @return
     */
    public List<SysDept> getDeptById(String id) {
        if(StringUtils.isNotEmpty(id)){
            return this.list(new QueryWrapper<SysDept>()
                    .eq(SysDept.ColName.parent_id.toString(), id)
                    .orderByAsc(SysDept.ColName.dept_order.toString(), SysDept.ColName.dept_id.name()));
        }else {
            return this.list(new QueryWrapper<SysDept>().isNull(SysDept.ColName.parent_id.toString())
                    .orderByAsc(SysDept.ColName.dept_order.toString(), SysDept.ColName.dept_id.name()));
        }
    }

    /**
     * 查询部门下的子部门（分页）
     * @param id
     * @return
     */
    @Override
    public List<SysDeptVO> getDeptPage(String id, String deptName) {
        List<SysDeptVO> sysDeptVOList = new ArrayList<>();
        List<SysDept> sysDeptList = new ArrayList<>();
        if(StringUtils.isNotEmpty(id)){
            sysDeptList = this.list(new QueryWrapper<SysDept>().eq(SysDept.ColName.parent_id.toString(),id)
                                                            .like(deptName != null,SysDept.ColName.dept_name.toString(),deptName));
            sysDeptVOList = getSysDeptVOS(sysDeptList);
            return sysDeptVOList;
        }else{
            sysDeptList = this.list(new QueryWrapper<SysDept>().isNull(SysDept.ColName.parent_id.toString())
                                                            .like(deptName != null,SysDept.ColName.dept_name.toString(),deptName));
            sysDeptVOList = getSysDeptVOS(sysDeptList);
            return sysDeptVOList;
        }
    }

    /*private List<SysDeptVO> getSysDeptVOPageVO(List<SysDept> sysDeptList) {
        List<SysDeptVO> sysDeptVOS = new ArrayList<>();
        sysDeptList.forEach(param->{
            SysDeptVO sysDeptVO = param.convertToVO();
            String deptId = sysDeptVO.getDeptId();
            List<SysDeptPosition> sysDeptPositionList = baseMapper.getSysDeptPosition(deptId);
            sysDeptVO.setSysDeptPositionList(sysDeptPositionList);
            sysDeptVOS.add(sysDeptVO)
        });
        return sysDeptVOS;
    }*/

    @Override
    public List<SysDeptVO> getDeptAllById(String id) {
        List<SysDept> sysDeptList = new ArrayList<>();
        if(StringUtils.isNotEmpty(id)){
            sysDeptList = this.list(new QueryWrapper<SysDept>().eq(SysDept.ColName.parent_id.toString(),id));
            return getSysDeptVOS(sysDeptList);
        }else{
            sysDeptList = this.list(new QueryWrapper<SysDept>().isNull(SysDept.ColName.parent_id.toString()));
            return getSysDeptVOS(sysDeptList);
        }
    }

    @Override
    public void deleteDeptUser(String userId) {
        baseMapper.deleteDeptUser(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateManagerPost(String deptId, String positionId, Integer state) {
        //修改部门下的岗位为管理岗位
        baseMapper.updateManagerPost(deptId,positionId,state);
    }

    private List<SysDeptVO> getSysDeptVOS(List<SysDept> sysDeptList) {
        List<SysDeptVO> sysDeptVOList = new ArrayList<>();
        sysDeptList.forEach(param -> {
            SysDeptVO sysDeptVO = param.convertToVO();
            String deptId = sysDeptVO.getDeptId();
            List<SysDeptPosition> sysDeptPositionList = baseMapper.getSysDeptPosition(deptId);
            sysDeptVO.setSysDeptPositionList(sysDeptPositionList);
            sysDeptVOList.add(sysDeptVO);
        });
        return sysDeptVOList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertDeptInfo(SysDeptVO sysDeptVO) {
        //获取部门负责岗位id
        String positionId = sysDeptVO.getPositionId();
        //获取表中最大的id
        String id = this.queryMaxDeptId(sysDeptVO.getParentId());
        sysDeptVO.setDeptId(id);
        this.save(sysDeptVO.convertToEntity());
        //新增部门岗位信息
        List<SysDeptPosition> sysDeptPositionList = sysDeptVO.getSysDeptPositionList();
        sysDeptPositionList.forEach(param->{
            //当岗位为部门负责人岗位时，charge_post为1
            if(param.getPositionId().equals(positionId)){
                param.setChargePost(1);
            }else {
                param.setChargePost(0);
            }
            param.setDeptId(sysDeptVO.getDeptId());
            param.setManagerPost(0);
            baseMapper.saveSysDeptPosition(param);
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDeptInfo(SysDeptVO sysDeptVO) {
        //当子部门变成父级部门时
        if(StringUtils.isEmpty(sysDeptVO.getParentId()) && sysDeptVO.getDeptId().length() > 3){
            //获取表中最大的id
            String id = this.queryMaxDeptId(sysDeptVO.getParentId());
            sysDeptVO.setDeptId(id);
            this.save(sysDeptVO.convertToEntity());
        }else {
            this.updateById(sysDeptVO.convertToEntity());
        }
        //获取部门岗位
        List<SysDeptPosition> sysDeptPositionList = sysDeptVO.getSysDeptPositionList();
        //查询数据库中的部门岗位
        List<SysDeptPosition> oldSysDeptPositionList = baseMapper.getSysDeptPosition(sysDeptVO.getDeptId());
        //当修改的岗位>数据库以及存在的数据时 新增新加的岗位
        for (SysDeptPosition newDetpPosition:sysDeptPositionList) {
            boolean isExsit = isExsitSysDeptPosition(newDetpPosition, oldSysDeptPositionList);
            if (!isExsit){
                newDetpPosition.setChargePost(0);
                newDetpPosition.setManagerPost(0);
                newDetpPosition.setDeptId(sysDeptVO.getDeptId());
                baseMapper.saveSysDeptPosition(newDetpPosition);
            }
        }
        //当修改的岗位<数据库以及存在的数据时 删除数据库已经存在的数据
        for (SysDeptPosition oldDetpPosition:oldSysDeptPositionList) {
            boolean isExsit = isExsitSysDeptPosition(oldDetpPosition, sysDeptPositionList);
            if (!isExsit){
                String deptId = oldDetpPosition.getDeptId();
                String positionId = oldDetpPosition.getPositionId();
                //删除部门岗位
                baseMapper.deleteSysDeptPosition(deptId,positionId);
                //在删除部门岗位之后 需要修改把这个部门岗位设为上级管理岗位
                baseMapper.updateSysDeptPosition(deptId,positionId);
            }
        }
        //修改部门负责人,先查询该部门下的部门负责人和sysDeptVO.getPositionId()是否一致
        String positionId = baseMapper.selectSysDeptPosition(sysDeptVO.getDeptId());
        //如果不一致，则需修改之前的岗位为0，现传来的为1
        if(!sysDeptVO.getPositionId().equals(positionId)){
            baseMapper.updateOldChargePost(sysDeptVO.getDeptId(),positionId);
            baseMapper.updateNewChargePost(sysDeptVO.getDeptId(),sysDeptVO.getPositionId());
        }

    }

    private boolean isExsitSysDeptPosition(SysDeptPosition sdp, List<SysDeptPosition> list){
        for(SysDeptPosition tmp:list){
            if (tmp.getDeptId().equals(sdp.getDeptId()) && tmp.getPositionId().equals(sdp.getPositionId())){
                return true;
            }
        }
        return false;
    }

    public String queryMaxDeptId(String parentId) {
        String deptId = null;
        if(StringUtils.isNotEmpty(parentId)){
            deptId = baseMapper.queryMaxDeptIdByParentId(parentId);
            return StringUtils.isEmpty(deptId) ? parentId + "001" : deptId;
        }else{
            deptId = baseMapper.queryMaxDeptId();
            return StringUtils.isEmpty(deptId)? "001" : deptId;
        }
    }

    @Override
    public String getDeptList(String userId) {
        return baseMapper.getDeptList(userId);
    }

    @Override
    public String getMainDeptId(String userId) {
        return baseMapper.getMainDeptId(userId);
    }

}
